#pragma once
#include <sys/epoll.h>
#include <functional>
#include "Epoll.h"
#include "InetAddress.h"
#include "Socket.h"

// 前向声明 Epoll 类
class Epoll;

/**
 * Channel 类 - 封装文件描述符与 epoll 事件的关联
 * 
 * 每个 Channel 对象对应一个文件描述符 (fd)，管理该 fd 的事件监视状态
 * 与 Epoll 对象是多对一关系（多个 Channel 对应一个 Epoll 实例）
 */
class Channel {
private:
    int fd_ = -1;              ///< Channel 关联的文件描述符 (一对一关系)
    Epoll *ep_ = nullptr;       ///< 所属的 Epoll 对象 (多对一关系)
    bool inepoll_ = false;      ///< 是否已添加到 epoll 树
    
    uint32_t events_ = 0;       ///< 需要监视的事件:
    ///   - listenfd: EPOLLIN (监听新连接)
    ///   - clientfd: EPOLLIN (可读) | EPOLLOUT (可写)
    uint32_t revents_ = 0;      ///< 实际发生的事件 (由 epoll_wait 返回)


    std::function<void()> readcallback_;

public:
    /**
     * @brief 构造函数
     * @param ep 关联的 Epoll 对象指针
     * @param fd 关联的文件描述符
     */
    Channel(Epoll* ep, int fd);
    
    /**
     * @brief 析构函数
     */
    ~Channel();
    
    // 访问器函数
    int fd() const;           ///< 返回关联的文件描述符
    bool inpoll() const;      ///< 返回是否已添加到 epoll 树
    uint32_t events() const;  ///< 返回当前监视的事件集
    uint32_t revents() const; ///< 返回实际发生的事件集
    
    // 事件管理
    void useet();            ///< 设置使用边缘触发 (EPOLLET) 模式
    void enablereading();    ///< 启用读事件监视 (EPOLLIN)
    void setinepoll();       ///< 标记已添加到 epoll 树
    
    /**
     * @brief 设置实际发生的事件
     * @param ev 由 epoll_wait 返回的事件值
     */
    void setrevents(uint32_t ev);


    void handleevent();//事件处理函数,epoll_wait返回的时候执行它


    void newconnection(Socket* servsock);
    void onmessage();

    void setreadcallback(std::function<void()> f);
};